﻿using System;

namespace 多维数组
{
    class Program
    {
        static void Main(string[] args)
        {
            /*
             * 数组：数据的组合，数据的集合，它必须是同一种数据类型
             * 指定一个类型+一组中括号+变量名
             * 数组是引用类型
             * 数组的创建必须有初始化或者指定大小
             * 当指定了数组的大小，并且使用{}赋初始值时，初始值要写够这么多数据
             * 但制定了数组的大小，但是没有使用{}赋初始值的时候，里面每一项是这种数据类型的默认值
             */
            //数组的声明
            string[] a;//声明不赋值
            string[] b = null;//赋了默认值
            string[] c = default;//default关键字代表赋这个类型的默认值
            string[] d = { "aa", "bb", "cc" };//声明的时候把值都赋了 简写方式
            string[] e = new string[2];//代表声明了两个空置，根据下标赋值
            string[] f = new string[3] { "33", "44", "55" };//声明数组数量的同时并给数组赋值

            //数组的使用
            //1.如果数组赋值为null，你必须对数组赋有效值
            c = new string[2] { "张三", "李四" };//为c进行赋值

            //2.取数组指定位置的值
            string person = c[1];//通过索引取值，这句话里面的“1”就是索引，索引是从0开始到数组大小-1的范围
            Console.WriteLine(person);

            //3怎么把数据存储到数组
            c[1] = "66";
            Console.WriteLine(c[1]);

            //遍历数组 可以用for循环进行遍历 
            for (int i = 0; i < f.Length; i++)
            {
                Console.WriteLine(f[i]);
            }
            //二维数组
            //声明二维数组在方括号里添加一个逗号来代表二维数组
            int[,] num = { { 11, 22, 33, 44, 55 }, { 66, 77, 88, 99, 100 } };//简写方式
            int[,] num1;//声明了二维数组这么一个类型
            int[,] num2 = null;//声明了二维数组并给了一个默认值
            int[,] num3 = new int[,] { { 11, 22, 33, 44, 55 }, { 66, 77, 88, 99, 100 } };//声明了二维数组并给它里面赋值

            var arrLenght = num.GetLength(0);
            var arrLenght0 = num.GetLength(1);
            Console.WriteLine($"第 0 维的数组长度是={arrLenght}");
            Console.WriteLine($"第 1 维的数组长度是={arrLenght0}");
            for (int i = 0; i < arrLenght; i++)
            {
                for (int j = 0; j < arrLenght0; j++)
                {
                    Console.WriteLine($"{nameof(num)}[{i},{j}]={num[i, j]}");
                }
            }

            // 交错数组 : 本质 就是数组中的值他还是数组 → 还是数组的数组
            //与多维数组区别在于：
            //1. 里面的数组长度不定，而多维数组必须大小一致
            //2. ageArrArr.Length 是数组本身的数据大小，在此处是 3 ,但是多维数组的 Length 是全部数据
            //3. 本质上还是一维数组 ， Rank = 1
            static void ArrayArr()
            {
                //数组的数组
                int[][] ageArrArr = new int[][]
                 {
               new int[]{11,22 },
               new int[]{11,22 },
               new int[]{11,22,33 }, //跟多维数组比起来有个好处，能够存多个不同长度的数组
                 };


                for (int i = 0; i < ageArrArr.Length; i++)
                {
                    var ls = ageArrArr[i].Length;
                    for (int j = 0; j < ls; j++)
                    {
                        int value = ageArrArr[i][j];
                        Console.WriteLine($"第一个数组的第 {i} 个的值的第 {j} 个值是：{value}");
                    }
                }

                Console.WriteLine($"第一个数组的第 3 个值第三个值是 ：{ageArrArr[2][2]}");

                //交错数组的声明：
                // 必须声明外围的数组的长度，不声明必报错：数组必须有大小或者有初始值
                int[][][] aaarr0 = new int[2][][];
                // 可以使用花括号表示，如果仅有一对花括号代表数组为空
                int[][][] aaarr1 = new int[][][] { };
                //报错：Index was outside the bounds of the array. 
                // Index 索引的意思
                // Bounds ： 边界
                // outside ： 在xxxx外面
                // 索引超出了数组的边界
                // 如果交错数组的里面是空数组，不能采用下面的方式赋值，因为会超索引
                //aaarr1[0][0] = new int[3] { 11, 12, 13 }; 
                //Console.WriteLine( aaarr1[0][0]);


                int[][][] aaarr2 = new int[][][]
                {
                new int [][]{ new int[] {11,22 }, new int[] { 33, 44 } },
                new int [][]{ new int[] {111,222 }, new int[] { 333, 444 } },
                new int [][]{ new int[] {11111,22222 }, new int[] { 3333, 4444 } }
                };

                // 测试输出 交错数组的 维度信息
                Console.WriteLine($"{nameof(ageArrArr)} 维度 = {ageArrArr.Rank}");
                Console.WriteLine($"{nameof(aaarr2)} 维度 = {aaarr2.Rank}");

                // 交错数组的 取值
                int value0 = aaarr2[1][1][0];
                Console.WriteLine($"第一个数组的第二个值的第二个值的第一个值 ： {value0}");
                Console.WriteLine($"Before : {aaarr2[2][0][1]}"); //before :之前
                                                                  // 交错数组的赋值
                aaarr2[2][0][1] = 55555;
                Console.WriteLine($"After : {aaarr2[2][0][1]}"); //After :之后

                // 交错数组的遍历
                for (int i = 0; i < aaarr2.Length; i++)
                {
                    for (int j = 0; j < aaarr2[i].Length; j++) //aaarr2[i] 取数组的某一个值
                    {
                        //aaarr2[i][j] 取交错数组的第 i 个值（数组）的第 j 个值
                        for (int k = 0; k < aaarr2[i][j].Length; k++)
                        {
                            Console.WriteLine($"第 {i + 1} 个数组的第 {j + 1} 个值的第 {k + 1} 个值是： {aaarr2[i][j][k]}");
                        }
                    }
                }
            }

            // 三维数组
            static void TestSanArray()
            {
                //数组的声明 ： 在表示数组的中括号中使用 2个 逗号
                // 在此处，一对 花括号 代表一个数组
                //三维数组声明要在方括号里添加2个逗号。以此类推
                int[,,] san =
                {
                {{1,2,3},{4,5,6 },{7,8,9 } },
                {{11,22,33},{44,55,66 },{77,88,99 } },
                {{111,222,333},{444,555,666 },{777,888,999 } },
            };

                // 取值
                int value = san[2, 1, 1];
                Console.WriteLine($"第三个值的第二个值的第二个值是： {value}");
                // 赋值
                Console.WriteLine($"Before : {san[2, 2, 1]}");
                san[2, 2, 1] = 66666;
                Console.WriteLine($"After : {san[2, 2, 1]}");
                // For 遍历
                int length0 = san.GetLength(0);
                int length1 = san.GetLength(1);
                int length2 = san.GetLength(2);
                for (int i = 0; i < length0; i++)
                {
                    for (int j = 0; j < length1; j++)
                    {
                        for (int k = 0; k < length2; k++)
                        {
                            Console.WriteLine($"第 {i + 1} 个值的 第 {j + 1} 个值的 第 {k + 1} 个值是{san[i, j, k]}");
                        }
                    }
                }
                // Foreach 遍历
                foreach (var item in san)
                {
                    Console.WriteLine("它的值是：" + item);
                }
            }

            static void TestSunSanArray()
            {
                int[,,] array3 =
               {
            {
                {10,11},{11,11},{12,11},{13,11}
            },

            {  {20,12},{21,12},{22,12},{23,12}
            },
                  {  {20,12},{21,12},{22,12},{23,12}
            },
            {
                {30,13},{31,13},{32,13},{33,1333}
            }

           };
                }
        }
    }
}




